#include "globals.h"

static void sig_alrm(int signo);
static sigjmp_buf jmpbuf;
void
parse_vm_val(
        char *str,
        int *val
        );

int main()
{
    int     sockfd;
    struct sockaddr_un cliaddr;
    char filename[] = "/tmp/may.XXXXXX\0";
    int vm_no = 0;
    char msg[1000];
    char ip_addr[16];
    int portnum;

    sockfd = Socket(AF_LOCAL, SOCK_DGRAM, 0);

    if( mkstemp(filename) == -1 )
    {
        printf("Temporary file cannot be created\n");
    }

    unlink(filename);

    bzero(&cliaddr, sizeof(cliaddr));       
    cliaddr.sun_family = AF_LOCAL;
    strcpy(cliaddr.sun_path, filename);

    Bind(sockfd, (SA *) &cliaddr, sizeof(cliaddr));
    Signal(SIGALRM, sig_alrm);

    while(1)
    {
        int portno = 4094;              /* Well-known port */
        struct hostent * hptr;
        char vm[5] = "vm\0\0\0";
        char addr[INET_ADDRSTRLEN] = "\0"; 
        char msg[] = "Request for Day-time service\0";
        int flag = 0;                           /* Forced Route Discovery */
        char  temp[3] = "\0" ;          
        int num_tries;
        char vm_no_str[100];

        printf("\nEnter one amongst the following numbers to Connect to appropriate Server: \n1-VM1 \n2-VM2 \n3-VM3 \n4-VM4 \n5-VM5 \n6-VM6 \n7-VM7 \n8-VM8 \n9-VM9 \n10-VM10\n");
        scanf("%s", vm_no_str);
        parse_vm_val(vm_no_str, &vm_no);

        if(vm_no - 10 > 0 || vm_no - 10 < -9)
        {
            printf("Inappropriate choice\n");
            continue;
        }

        sprintf(temp,"%d",vm_no);
        strcat(vm, temp);       
        printf("VM no %s \n", vm);
        hptr = gethostbyname(vm);               

        if ( (hptr = gethostbyname(vm)) == NULL) //Checks validity of Domain name
        {
            err_msg("GET HOST BY NAME ERROR :: %s: %s\n", vm, hstrerror(h_errno));
            exit(1);
        }

        Inet_ntop(hptr->h_addrtype, *hptr->h_addr_list, addr, sizeof(addr));

        printf("IP Address of %s is %s\n", vm, addr);
        num_tries = 0;

sendagain:

        if (num_tries == 0)
        {
            //
            // First time.
            //

            msg_send(sockfd, addr, portno, msg, 0);
        }
        else
        {
            //
            // Retransmit. Forece route discovery.
            //

            msg_send(sockfd, addr, portno, msg, 1);
        }
        
        alarm(CLIENT_TIMEOUT);

        if (sigsetjmp(jmpbuf, 1) != 0) 
        {
            num_tries++;

            if (num_tries > 1)
            {
                //
                // Giving up.
                //
                
                printf("Giving up. Client at %s: timeout from %s.\n",
                        get_vmname_from_ip(get_odr_ip()),
                        get_vmname_from_ip(addr));

                continue;
            }
            else
            {
                //
                // try again.
                //
                
                printf("Client at %s: timeout from %s.\n",
                        get_vmname_from_ip(get_odr_ip()),
                        get_vmname_from_ip(addr));

                goto sendagain;
            }
        }

        msg_receive(sockfd, msg, ip_addr, &portnum);

        //
        // Cancel the alarm.
        //

        alarm(0);
    }

    return 0;
}

static void
sig_alrm(int signo)
{
//    printf("ALARM!!\n");
    siglongjmp(jmpbuf, 1);
}

void
parse_vm_val(
        char *str,
        int *val
        )
{
    int ix = 0;

    for(ix = 0; ix < strlen(str); ix++)
    {
        if (str[ix] - '0' < 0 || str[ix] - '9' > 9)
        {
            printf("invalid char as arguments.\n");
            *val = -1;
            return;
        }
    }

    *val = atoi(str);
}


